package com.leetcode.threadtest;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.*;

/**
 * -@Version 1.0
 * -@Author:Vpen
 * -@Date:2021/1/28 21:18
 * -@Content:
 */
public class ThreadTest {
    
    @Test
    public void test5() throws InterruptedException {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i < 5; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();//获得
                    System.out.println(Thread.currentThread().getName()+"获得");
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(Thread.currentThread().getName()+"释放");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();//释放
                }
            }).start();
        }
        TimeUnit.SECONDS.sleep(5);
    }

    @Test
    public void test4() throws InterruptedException {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
            System.out.println("已经集齐了5个线程");
        });

        for (int i = 1; i <= 5; i++) {
            final int temp=i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"收集第"+temp+"个线程");
                try {
                    cyclicBarrier.await();//等待线程累加到5个
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },"线程"+String.valueOf(i)).start();
        }

        TimeUnit.SECONDS.sleep(1);

    }

    @Test
    public void test3() throws InterruptedException {
        CountDownLatch count = new CountDownLatch(5);

        for (int i = 1; i <= 5; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+" is Go");
                count.countDown();  // 数量-1
             },"线程"+String.valueOf(i)).start();
        }

        count.await();// 等待计数器归零
//        TimeUnit.SECONDS.sleep(1);
        System.out.println("Thread is Over");

    }


    @Test
    public void test2() throws InterruptedException {
        // 并发的时候容易引发线程同时修改异常ConcurrentModificationException
       // ArrayList<String> list = new ArrayList<>();

        // 使用工具类是ArrayList变成线程安全
//        List<String> list = Collections.synchronizedList(new ArrayList<>());

        // 方法二
        List<String> list = new CopyOnWriteArrayList<>();

        for (int i = 1; i <=100 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,6));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

        TimeUnit.SECONDS.sleep(1);

    }
    

    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.inc();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"线程A").start();


        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.dec();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"线程B").start();
    }


    @Test
    public void test1() throws InterruptedException {
        Data data = new Data();
        Thread threadA = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.inc();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程A");


        Thread threadB = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.dec();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程B");

        Thread threadC = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.inc();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程C");

        Thread threadD = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.dec();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程D");

        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();

        threadA.join();
        threadB.join();
        threadC.join();
        threadD.join();


        System.out.println("main over");
    }

}



class Data{
    public int num=0;
    public synchronized void inc() throws InterruptedException {
//        if (num != 0){
//            this.wait();
//        }

        while (num != 0){
           this.wait();
       }
        num++;
        System.out.println(Thread.currentThread().getName()+"生产了"+num+"个商品");
        this.notifyAll();
    }
    public synchronized void dec() throws InterruptedException {
        while (num == 0){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"消费了"+num+"个商品");
        this.notifyAll();

    }
}